package com.ude.pim.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ude.pim.common.R;
import com.ude.pim.dto.CaseSubDelayApplyDTO;
import com.ude.pim.entity.CaseSub;
import com.ude.pim.entity.CaseSubDelayApply;
import com.ude.pim.mapper.CaseSubDelayApplyMapper;
import com.ude.pim.service.CaseSubDelayApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ude.pim.service.CaseSubService;
import com.ude.pim.utils.PIMConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yb
 * @since 2023-08-21
 */
@Service
public class CaseSubDelayApplyServiceImpl extends ServiceImpl<CaseSubDelayApplyMapper, CaseSubDelayApply> implements CaseSubDelayApplyService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private CaseSubService caseSubService;

    /**
     * 1. 原则：特定 专案阶段的特定负责人一个时间内只能有一个类型的申请处于申请中
     *
     * @param caseSubDelayApply
     * @return
     */
    @Override
    public R<String> saveWithCheck(CaseSubDelayApply caseSubDelayApply) {
        String type = caseSubDelayApply.getType();
        LambdaQueryWrapper<CaseSubDelayApply> lqw = new LambdaQueryWrapper<>();
        //类型筛选
        lqw.eq(CaseSubDelayApply::getType, type);
        //状态筛选
        lqw.eq(CaseSubDelayApply::getStatus, 0);
        //申请人筛选
        lqw.eq(CaseSubDelayApply::getApplyId, caseSubDelayApply.getApplyId());
        //专案阶段筛选
        lqw.eq(CaseSubDelayApply::getCaseSubId, caseSubDelayApply.getCaseSubId());
        CaseSubDelayApply one = this.getOne(lqw);
        if (one != null)
            return R.error("该专案子阶段您已经有一个该类型的申请处于审核中，无法再次发起同一类型的申请");

        caseSubDelayApply.setStatus(0);
        caseSubDelayApply.setCreateTime(LocalDateTime.now());

        //设定预计时间
        LocalDateTime predictTime = caseSubService.getPredictTime(caseSubDelayApply.getCaseSubId());
        predictTime = predictTime.plusDays(caseSubDelayApply.getApplyDays());
        caseSubDelayApply.setPredictTime(predictTime);

        this.save(caseSubDelayApply);
        return R.success("申请成功，请关注审核结果");
    }

    @Override
    public R<List<CaseSubDelayApplyDTO>> checkingList() {
        LambdaQueryWrapper<CaseSubDelayApply> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CaseSubDelayApply::getStatus, 0);
        List<CaseSubDelayApply> list = this.list(lqw);
        List<CaseSubDelayApplyDTO> collect = map2DTO(list);
        return R.success(collect);
    }

    /**
     * 1.判断是通过还是拒绝
     * 2.如果是通过，且延期原因是外界因素延期，则直接进行加法赋值
     * 3.如果是人为因素延期，则对子阶段申请天数进行加法赋值
     * 4. 审核通过后，数据会变化，需要移除缓存
     *
     * @param caseSubDelayApplyDTO
     * @return
     */
    @Override
    public R<String> judge(CaseSubDelayApplyDTO caseSubDelayApplyDTO) {
        //通过
        if (caseSubDelayApplyDTO.getStatus() == 1) {
            //移除缓存
            CaseSub caseSub = caseSubService.getById(caseSubDelayApplyDTO.getCaseSubId());
            stringRedisTemplate.delete(PIMConstants.CASE_SUB_LIST+caseSub.getCaseId());

            if (caseSubDelayApplyDTO.getType().equals("外界因素延期")) {
                caseSubService.addUnforcedDays(caseSubDelayApplyDTO.getCaseSubId(), caseSubDelayApplyDTO.getApplyDays());
            } else {
                caseSubService.addApplyDelay(caseSubDelayApplyDTO.getCaseSubId(), caseSubDelayApplyDTO.getApplyDays());
            }
        }
        caseSubDelayApplyDTO.setCheckTime(LocalDateTime.now());
        this.updateById(caseSubDelayApplyDTO);
        return R.success("审核通过成功");
    }

    @Override
    public R<List<CaseSubDelayApplyDTO>> getByUserAndStatus(CaseSubDelayApply caseSubDelayApply) {
        LambdaQueryWrapper<CaseSubDelayApply> lqw = new LambdaQueryWrapper<>();
        //按申请人查询
        if (caseSubDelayApply.getApplyId()!=null)
            lqw.eq(CaseSubDelayApply::getApplyId,caseSubDelayApply.getApplyId());
        //按专案子流程查询
        if(caseSubDelayApply.getCaseSubId()!=null)
            lqw.eq(CaseSubDelayApply::getCaseSubId,caseSubDelayApply.getCaseSubId());
        //按申请类型查询
        if(caseSubDelayApply.getType()!=null)
            lqw.eq(CaseSubDelayApply::getType,caseSubDelayApply.getType());

        lqw.eq(CaseSubDelayApply::getStatus,caseSubDelayApply.getStatus());
        List<CaseSubDelayApply> list = this.list(lqw);
        List<CaseSubDelayApplyDTO> collect = map2DTO(list);
        return R.success(collect);
    }

    //封装pojo 2 dto 方法
    public List<CaseSubDelayApplyDTO> map2DTO(List<CaseSubDelayApply> list){
        return list.stream().map(s -> {
            CaseSubDelayApplyDTO dto = new CaseSubDelayApplyDTO();
            BeanUtils.copyProperties(s, dto);
            //专案名
            String nameJson = stringRedisTemplate.opsForValue().get("caseSubId2Name:" + s.getCaseSubId());
            Map<String, String> map = JSONUtil.toBean(nameJson, Map.class);
            dto.setCaseName(map.get("caseName"));
            dto.setSubName(map.get("subName"));
            //申请人姓名
            String applyName = stringRedisTemplate.opsForValue().get("userId2Name:" + s.getApplyId());
            dto.setApplyName(applyName);

            return dto;
        }).collect(Collectors.toList());
    }
}
